<!DOCTYPE html>
<html lang="zh-Hans">
<head>

    <!--[if lt IE 9]>
        <style>body {display: none; background: none !important} </style>
        <meta http-equiv="Refresh" Content="0; url=//outdatedbrowser.com/" />
    <![endif]-->

<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="format-detection" content="telephone=no" />
<meta name="author" content="FreeShow" />



<meta property="og:type" content="article">
<meta property="og:title" content="Java之集合框架">
<meta property="og:url" content="https://freeshow.github.io/Programming/Java/Java之集合框架/index.html">
<meta property="og:site_name" content="FreeShow">
<meta property="og:updated_time" content="2017-03-28T08:06:22.450Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Java之集合框架">

<link rel="apple-touch-icon" href= "/apple-touch-icon.png">


    <link rel="alternate" href="/atom.xml" title="FreeShow" type="application/atom+xml">



    <link rel="shortcut icon" href="/favicon.ico">



    <link href="//cdn.bootcss.com/animate.css/3.5.1/animate.min.css" rel="stylesheet">



    <link href="//cdn.bootcss.com/fancybox/2.1.5/jquery.fancybox.min.css" rel="stylesheet">



    <script src="//cdn.bootcss.com/pace/1.0.2/pace.min.js"></script>
    <link href="//cdn.bootcss.com/pace/1.0.2/themes/blue/pace-theme-minimal.css" rel="stylesheet">


<link rel="stylesheet" href="/css/style.css">



<link href="//cdn.bootcss.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet">


<title>Java之集合框架 | FreeShow</title>

<script src="//cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script>
<script src="//cdn.bootcss.com/clipboard.js/1.5.10/clipboard.min.js"></script>

<script>
    var yiliaConfig = {
        fancybox: true,
        animate: true,
        isHome: false,
        isPost: true,
        isArchive: false,
        isTag: false,
        isCategory: false,
        fancybox_js: "//cdn.bootcss.com/fancybox/2.1.5/jquery.fancybox.min.js",
        scrollreveal: "//cdn.bootcss.com/scrollReveal.js/3.1.4/scrollreveal.min.js",
        search: true
    }
</script>


    <script>
        yiliaConfig.jquery_ui = [true, "//cdn.bootcss.com/jqueryui/1.10.4/jquery-ui.min.js", "//cdn.bootcss.com/jqueryui/1.10.4/css/jquery-ui.min.css"];
    </script>



    <script> yiliaConfig.rootUrl = "\/";</script>






</head>
<body>
  <div id="container">
    <div class="left-col">
    <div class="overlay"></div>
<div class="intrude-less">
    <header id="header" class="inner">
        <a href="/" class="profilepic">
            <img src="/img/avatar.png" class="animated zoomIn">
        </a>
        <hgroup>
          <h1 class="header-author"><a href="/">FreeShow</a></h1>
        </hgroup>

        
        <p class="header-subtitle">在追求艺术的道路上狂奔</p>
        

        
            <form id="search-form">
            <input type="text" id="local-search-input" name="q" placeholder="search..." class="search form-control" autocomplete="off" autocorrect="off" searchonload="false" />
            <i class="fa fa-times" onclick="resetSearch()"></i>
            </form>
            <div id="local-search-result"></div>
            <p class='no-result'>No results found <i class='fa fa-spinner fa-pulse'></i></p>
        


        
            <div id="switch-btn" class="switch-btn">
                <div class="icon">
                    <div class="icon-ctn">
                        <div class="icon-wrap icon-house" data-idx="0">
                            <div class="birdhouse"></div>
                            <div class="birdhouse_holes"></div>
                        </div>
                        <div class="icon-wrap icon-ribbon hide" data-idx="1">
                            <div class="ribbon"></div>
                        </div>
                        
                        <div class="icon-wrap icon-link hide" data-idx="2">
                            <div class="loopback_l"></div>
                            <div class="loopback_r"></div>
                        </div>
                        
                        
                        <div class="icon-wrap icon-me hide" data-idx="3">
                            <div class="user"></div>
                            <div class="shoulder"></div>
                        </div>
                        
                    </div>
                    
                </div>
                <div class="tips-box hide">
                    <div class="tips-arrow"></div>
                    <ul class="tips-inner">
                        <li>菜单</li>
                        <li>标签</li>
                        
                        <li>友情链接</li>
                        
                        
                        <li>关于我</li>
                        
                    </ul>
                </div>
            </div>
        

        <div id="switch-area" class="switch-area">
            <div class="switch-wrap">
                <section class="switch-part switch-part1">
                    <nav class="header-menu">
                        <ul>
                        
                            <li><a href="/">主页</a></li>
                        
                            <li><a href="/archives/">所有文章</a></li>
                        
                            <li><a href="/tags/">标签云</a></li>
                        
                            <li><a href="/about/">关于我</a></li>
                        
                        </ul>
                    </nav>
                    <nav class="header-nav">
                        <ul class="social">
                            
                                <a class="fa Email" href="mailto:877646746@qq.com" title="Email"></a>
                            
                                <a class="fa GitHub" href="http://github.com/freeshow" title="GitHub"></a>
                            
                                <a class="fa 新浪微博" href="http://weibo.com/freeshowself" title="新浪微博"></a>
                            
                                <a class="fa CSDN" href="http://blog.csdn.net/u011026329" title="CSDN"></a>
                            
                        </ul>
                    </nav>
                </section>
                
                
                <section class="switch-part switch-part2">
                    <div class="widget tagcloud" id="js-tagcloud">
                        <ul class="tag-list"><li class="tag-list-item"><a class="tag-list-link" href="/tags/Android/">Android</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/C/">C</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Crawler/">Crawler</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Hadoop/">Hadoop</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Hexo/">Hexo</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Java/">Java</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Linux/">Linux</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Python/">Python</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/SIP/">SIP</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Scala/">Scala</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Shell/">Shell</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Spark/">Spark</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Tools/">Tools</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/WebRTC/">WebRTC</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/XMPP/">XMPP</a></li></ul>
                    </div>
                </section>
                
                
                
                <section class="switch-part switch-part3">
                    <div id="js-friends">
                    
                      <a class="main-nav-link switch-friends-link" href="https://hexo.io">Hexo</a>
                    
                      <a class="main-nav-link switch-friends-link" href="https://github.com/freeshow">GitHub</a>
                    
                      <a class="main-nav-link switch-friends-link" href="http://freeshow.github.io/">FreeShow</a>
                    
                    </div>
                </section>
                

                
                
                <section class="switch-part switch-part4">
                
                    <div id="js-aboutme">我是一个喜欢无拘无束、追求自由、热爱分享的小小小码农！</div>
                </section>
                
            </div>
        </div>
    </header>                
</div>
    </div>
    <div class="mid-col">
      <nav id="mobile-nav">
      <div class="overlay">
          <div class="slider-trigger"></div>
          <h1 class="header-author js-mobile-header hide"><a href="/" title="回到主页">FreeShow</a></h1>
      </div>
    <div class="intrude-less">
        <header id="header" class="inner">
            <a href="/" class="profilepic">
                <img src="/img/avatar.png" class="animated zoomIn">
            </a>
            <hgroup>
              <h1 class="header-author"><a href="/" title="回到主页">FreeShow</a></h1>
            </hgroup>
            
            <p class="header-subtitle">在追求艺术的道路上狂奔</p>
            
            <nav class="header-menu">
                <ul>
                
                    <li><a href="/">主页</a></li>
                
                    <li><a href="/archives/">所有文章</a></li>
                
                    <li><a href="/tags/">标签云</a></li>
                
                    <li><a href="/about/">关于我</a></li>
                
                <div class="clearfix"></div>
                </ul>
            </nav>
            <nav class="header-nav">
                        <ul class="social">
                            
                                <a class="fa Email" target="_blank" href="mailto:877646746@qq.com" title="Email"></a>
                            
                                <a class="fa GitHub" target="_blank" href="http://github.com/freeshow" title="GitHub"></a>
                            
                                <a class="fa 新浪微博" target="_blank" href="http://weibo.com/freeshowself" title="新浪微博"></a>
                            
                                <a class="fa CSDN" target="_blank" href="http://blog.csdn.net/u011026329" title="CSDN"></a>
                            
                        </ul>
            </nav>
        </header>                
    </div>
    <link class="menu-list" tags="标签" friends="友情链接" about="关于我"/>
</nav>
      <div class="body-wrap"><article id="post-Programming/Java/Java之集合框架" class="article article-type-post" itemscope itemprop="blogPost">
  
    <div class="article-meta">
      <a href="/Programming/Java/Java之集合框架/" class="article-date">
      <time datetime="2016-07-23T15:03:47.000Z" itemprop="datePublished">2016-07-23</time>
</a>


    </div>
  
  <div class="article-inner">
    
      <input type="hidden" class="isFancy" />
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      Java之集合框架
    </h1>
  

      </header>
      
      <div class="article-info article-info-post">
        
    <div class="article-category tagcloud">
    <a class="article-category-link" href="/categories/编程语言/">编程语言</a>
    </div>


        
    <div class="article-tag tagcloud">
        <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Java/">Java</a></li></ul>
    </div>

        <div class="clearfix"></div>
      </div>
      
    
    <div class="article-entry" itemprop="articleBody">
      
          
        <p><excerpt in="" index="" |="" 首页摘要=""><br><a id="more"></a></excerpt></p>
<the rest="" of="" contents="" |="" 余下全文="">

<p><strong>18.1 集合概述</strong></p>
<p>1.集合框架在设计上需要满足几个目标。<br>    首先，框架必须是高性能的。基本集合(动态数组、链表、树以及哈希表)的实现是高效的。很少需要手动编写这些”数据 引擎”中的某个。<br>    其次，框架必须允许不同类型的集合以类似的方式进行工作，并且具有高度的互操作性。<br>    再次，扩展或改造集合必须易于实现。<br>    最后，必须添加可以将标准数组继承到集合框架中的机制。</p>
<p>2.算法是集合机制中的另一个重要部分。算法操作集合，并且被定义为Collections类中的静态方法。因此，所有集合都可以使用它们。每个集合都不需要实现特定于自己的版本，所发为操作集合提供了标准的方式。</p>
<p>3.于集合密切相关的另个一内容是Iterator接口。迭代器为访问集合中的元素提供了通用、标准的方式，每次访问一个元素。因此，迭代器提供了枚举集合内容的一种方式。因为每个集合都提供了迭代器，所以可以通过Iterator定义的方法访问所有集合类的元素。因此，对循环遍历集合的代码进行很小的修改，就可以将其用于循环遍历列表。</p>
<p>4.JDK 8添加了另一种类型的迭代器，叫做spliterator.简单的说，spliterator就是为并行迭代提供支持的迭代器。支持<br>spliterator的接口有Spliterator和支持基本类型的几个嵌入式接口。JDK 8还添加了用于基本类型的迭代器接口，例如<br>PrimitiveIterator和 PrimitiveIterator.OfDouble。</p>
<p><strong>18.3 集合接口</strong></p>
<pre><code>集合框架定义了一些核心接口，核心接口决定了集合类的本质特性。换句话说，具体类只是提供了标准接口的不同实现。
</code></pre><p><strong>1.Collection接口</strong></p>
<pre><code>Collection接口是构建集合框架的基础，因为定义集合的所有类都必须实现该接口。
Collection接口是泛型接口，其声明如下：

interface Collection&lt;E&gt;

其中，E指定了集合将要存储的对象的类型。Collection扩展了Iterable接口，这意味着所有集合都可以使用for-each风格的for循环进行遍历(回想一下，只有实现了Iterable接口的类才能通过for循环进行遍历)。 

Collection声明了所有集合都将拥有的核心方法。

通过调用add()方法可以将对象添加到集合中。
通过调用addAll()方法，可以将一个集合的所有内容添加到另一个集合中。

通过使用remove()方法可以移除一个对象。
为了移除一组对象，需要调用removeAll()方法。 
通过调用retainAll()方法，可以移除除了指定元素之外的所有元素。
要想移除满足某些条件的元素，可以使用removeIf()方法(Predicate是JDK 8新增的一个函数式接口)。 
为了清空集合，可以调用clear()方法。 

toArray()方法返回一个数组，其中包含调用集合中存储的元素。

通过调用equals()方法可以比较两个集合的相等性。&quot;相等&quot;的精确含义根据集合的不同可以有所区别。

另一个重要的方法是iterator()，它返回集合的一个迭代器。新的soliterator()方法返回集合的一个spliterator。当操作集合时会频繁用到迭代器。最后，stream()和parallelStream()方法返回使用集合作为元素来源的流(第29章将详细讨论新的Stream接口)。 
</code></pre><p><strong>2. List接口</strong></p>
<pre><code>List接口扩展了Collection，并且声明了用来存储一连串元素的集合的行为。在列表中可以使用从0开始的索引，通过元素的位置插入或访问元素。列表可以包含重复的元素。List是泛型接口，其声明如下：

interface List&lt;E&gt;

其中，E指定了将存储与列表中的对象的类型。

除了Collection定义的方法外，List还定义了自己的一些方法。

为了获得存储在特定位置的元素，使用对象的索引调用get()方法。为了给列表中的元素赋值，可以调用set()方法，并指定将要修改的对象的索引。为了查找对象的索引，可以使用indexOf()或laseIndexOf()方法。 

通过调用subList()方法，指定子列表的开始索引和结束索引，可以获得列表的子列表。
List定义的sort()方法是排序列表的一种方法。
</code></pre><p><strong>3. Set接口</strong></p>
<pre><code>Set接口定义了组(set)。它扩展了Collection接口，并且声明了集合中不允许有重复元素的组行为。所以，如果为组添加重复的元素，add()方法就会返回false。Set接口没有定义自己的其他方法。Set是泛型接口，其声明如下：

interface Set&lt;E&gt;

其中，E指定了组将包含的对象的类型。
</code></pre><p><strong>4. SortedSet接口</strong></p>
<pre><code>SortedSet接口扩展了Set接口，并且声明了以升序进行排序的组行为。SortedSet是泛型接口，其声明如下：

interface SortedSet&lt;E&gt;
</code></pre><p><strong>5. NavigableSet接口</strong></p>
<pre><code>NavigableSet接口扩展了SortedSet接口，并且该接口声明了支持基于最接近匹配原则检索元素的集合行为。
NavigableSet是泛型接口，其声明如下：

interface NavigableSet&lt;E&gt;
</code></pre><p><strong>6. Queue接口</strong></p>
<pre><code>Queue接口扩展了Collection接口，并且声明了队列的行为，队列通常是先进先出的列表。但是，还有基于其他准则的队列类型。Queue是泛型接口，其声明如下：

interface Queue&lt;E&gt;
</code></pre><p><strong>7. Deque接口</strong></p>
<pre><code>Deque接口扩展了Queue接口，并声明了双端队列的行为。双端队列既可以想标准队列那样先进先出，也可以像堆栈那样后进先出。Deque是泛型接口，其声明如下：

interface Deque&lt;E&gt; 

注意Deque接口提供了push()和pop()方法。这些方法使得Deque接口的功能与堆栈类似。
</code></pre><p><strong>18.4 集合类</strong> </p>
<pre><code>现在已经熟悉了集合接口，下面开始分析实现它们的标准类。其中的一些类提供了可以使用的完整实现。其他一些类是抽象的，它们提供了可以作为创建具体集合开始点的大体实现。作为一般规则，集合类不是同步的，但是在后面章节将会看到，可以获得它们的同步版本。

注意：
除了集合类之外，还有一些遗留的类，例如，Vector、Stack以及Hashtable，也进行了重新设计以支持集合。
</code></pre><p><strong>1. ArrayList类</strong></p>
<pre><code>ArrayList类扩展了AbstractList类并实现了List接口。ArrayList是泛型类，其声明如下：

class ArrayList&lt;E&gt;

在Java中，标准数组的长度是固定的。ArrayList类支持能够按需增长的动态数组。ArrayList就是元素为对象引用的长度可变的数组。

注意：遗留类Vector也支持动态数组。

ArrayList具有如下所示的构造函数：

ArrayList()
ArrayList(Collection&lt;? extends E&gt; c)
ArrayList(int capacity)

第1个构造函数构建了一个空的数组列表。
第2个构造函数构建了一个数组列表，使用集合c的元素进初始化。
第3个构造函数构建了一个初始容量为capacity的数组。
容量是用于存储元素的数组的大小，当数组中的元素等于容量时，当在向数组列表中添加元素时，容量会自动增长。

尽管存储对象时，ArrayList对象的容量会自动增长，但是可以调用ensureCapacity()方法以手动增长ArrayList对象的容量。如果事先知道将在集合中存储的元素比当前保存的元素多很多，你可能希望这么做。在开始时，一次性增加容量，从而避免以后多次重新分配内存。因为重新分配内存很耗时，阻止不必要的内存分配次数可以提高性能。

ensureCapacity()方法的签名如下：

void ensureCapacity(int cap)

其中，cap指定集合新的最小容量。

相反，如果希望减小ArrayList对象数组的大小，进而使其大小精确的等于当前容纳的元素的数量，可以调用trimToSize()方法，该方法如下所示：

void trimToSize()
</code></pre><p><strong>2.    LinkedList类</strong></p>
<pre><code>LinkedList类扩展了AbstractSequentialList类，实现了List、Deque以及Queue接口，并且它还提供了一种链表数据结构。
LinkedList是泛型类，其声明如下：

class LinkedList&lt;E&gt;

LinkedList具有两个构造函数，如下所示：

LinkedList()
LinkedList(Collection&lt;? extends E&gt; c)
</code></pre><p><strong>3.    HashSet类</strong></p>
<pre><code>HashSet类扩展了AbstractSet类并实现了Set接口，该类用于创建使用哈希表存储元素的集合。HashSet是泛型类，其声明如下：

class HashSet&lt;E&gt;

哈希表使用称之为散列的机制存储信息。在散列机制中，键的信息用于确定唯一的值，称为哈希码。然后将哈希码用作索引，在索引位置存储与键关联的数据。将键转换为哈希码是自动执行的————你永远不会看到哈希码本身。此外，你的代码不能直接索引哈希表。散列机制的优势是add()、contains()、remove()以及size()方法的执行时间保持不变，即使是对于比较大的数组也是如此。

HashSet类定义了一下构造函数：

HashSet()
HashSet(Collection&lt;? extends E&gt; c)
HashSet(int capacity)
HashSet(int capacity,float fillRatio)

HashSet不能保证元素的顺序，注意这一点很重要，因为散列处理的过程通常不创建有序的组。如果需要有序的进行存储，那么需要另外一个组，TreeSet是一个比较好的选择。

下面是演示了HashSet的一个例子：
</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line">import java.util.*;</div><div class="line"></div><div class="line">class HashSetDemo</div><div class="line">&#123;</div><div class="line">	public static void main(String[] args)</div><div class="line">	&#123;</div><div class="line">		HashSet&lt;String&gt; hs = new HashSet&lt;String&gt;();</div><div class="line">		</div><div class="line">		hs.add(&quot;Beta&quot;);</div><div class="line">		hs.add(&quot;Alpha&quot;);</div><div class="line">		ha.add(&quot;Eta&quot;);</div><div class="line">		</div><div class="line">		System.out.println(hs);</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<pre><code>输出：
[Eta,Beta,Alpha]

正如前面所解释的，元素不是按有序的顺序存储的，精确的输出可能不同。
</code></pre><p><strong>4.    LinkedHashSet类</strong></p>
<pre><code>LinkHashSet类扩展了HashSet类，它没有添加自己的方法。LinkedHashSet是泛型类，其声明如下：

class LinkedHashSet&lt;E

LinkedHashSet维护组中条目的一个链表。链表中条目的顺序也就是插入它们的顺序，这使得可以按照插入顺序迭代集合。换句话说，当使用迭代器遍历LinkedHashSet时，元素将以插入它们的顺序返回。
</code></pre><p><strong>5.    TreeSet类</strong></p>
<pre><code>TreeSet扩展了AbstractSet类并实现了NavigableSet接口，用于创建使用树进行存储的组。对象以升序存储，访问和检索速度相当快，这使得存储大量的、必须能够快速查找到的有序信息来说，TreeSet是极佳选择。

TreeSet是泛型类，其声明如下：

class TreeSet&lt;T&gt;

TreeSet具有如下构造函数：

TreeSet()
TreeSet(Collection&lt;? extends E&gt; c)
TreeSet(Comparator&lt;? super E&gt; comp)
TreeSet(SortedSet&lt;E&gt; ss)

第1种形式构建一个空树，将按照元素的自然顺序以升序进行存储。
第2种形式构建一个包含集合c中元素的树。
第3种形式构建了一个空树，将按照comp指定的比较器进行存储(比较器将在本章后面描述)
第4种形式构建一个包含ss中元素的树。

下面演示TreeSet类的一个例子：
</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line">class TreeSetDemo</div><div class="line">&#123;</div><div class="line">	public static void main(String[] args)</div><div class="line">	&#123;</div><div class="line">		TreeSet&lt;String&gt; ts = new TreeSet&lt;String&gt;();</div><div class="line">		</div><div class="line">		ts.add(&quot;C&quot;);</div><div class="line">		ts.add(&quot;A&quot;);</div><div class="line">		ts.add(&quot;B&quot;);</div><div class="line">		ts.add(&quot;E&quot;);</div><div class="line">		ts.add(&quot;F&quot;);</div><div class="line">		ts.add(&quot;D&quot;);</div><div class="line">		</div><div class="line">		System.out.println(ts);</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<pre><code>该程序输出：
[A,B,C,D,E,F]
</code></pre><p><strong>6.    PriorityQueue类</strong></p>
<pre><code>PriorityQueue扩展了AbstractQueue类并实现了Queue接口，用于创建根据队列的比较器来判定优先次序的队列。
PriorityQueue是泛型类，其声明如下：

class PriorityQueue&lt;E&gt;

PriorityQueue是动态的、按需增长的。

PriorityQueue定义了一下7个构造函数：

PriorityQueue()
PriorityQueue(int capacity)
PriorityQueue(Comparator&lt;? super E&gt; comp) (JDK 8新增)
PriorityQueue(int capacity,Comparator&lt;? super E&gt; comp)
PriorityQueue(Collection&lt;? extends E&gt; c)
PriorityQueue(PriorityQueue&lt;? extends E&gt; c)
PriorityQueue(SortedSet&lt;? extends E&gt; c)

第1个构造函数构建一个空队列，其实容量为11.
第2个构造函数构建一个具有指定初始容量的的队列。
第3个构造函数指定了一个比较器。
第4个构造函数构建具有指定容量和比较器的队列。
最后3个构造函数创建使用参数c传递过来的集合中的元素进行初始化的队列。
对于由这些构造函数创建的所有队列，当添加元素时，容量都会自动增长。

当创建PriorityQueue对象时，如果没有指定比较器，将使用队列中存储数据类型的默认比较器。默认比较器以升序对队列进行排序。但是，通过提供定制的比较器，可以指定不同的排序模式。
</code></pre><p><strong>7.    ArrayDeque类</strong></p>
<pre><code>ArrayDeque扩展了AbstractCollection类并实现了Deque接口，没有添加自己的方法。ArrayDeque是泛型类，其声明如下：

class ArrayDeque&lt;E&gt;

ArrayDeque定义了以下构造函数：

ArrayDeque()
ArrayDeque(int size)
ArrayDeque(Collection&lt;? extends E&gt; c)

下面演示了ArrayDeque，这里使用它来创建一个堆栈：
</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div></pre></td><td class="code"><pre><div class="line">import java.util.*;</div><div class="line"></div><div class="line">class ArrayDequeDemo</div><div class="line">&#123;</div><div class="line">	public static void main(String[] args)</div><div class="line">	&#123;</div><div class="line">		ArrayDeque&lt;String&gt; ad = new ArrayDeque&lt;&gt;();</div><div class="line">		</div><div class="line">		//Use an ArrayDeque like a stack</div><div class="line">		ad.push(&quot;A&quot;);</div><div class="line">		ad.push(&quot;B&quot;);</div><div class="line">		ad.push(&quot;D&quot;);</div><div class="line">		ad.push(&quot;E&quot;);</div><div class="line">		ad.push(&quot;F&quot;);</div><div class="line">		</div><div class="line">		System.out.print(&quot;Poping the stack: &quot;);</div><div class="line">		</div><div class="line">		while(ad.peek() != null)</div><div class="line">		&#123;</div><div class="line">			System.out.print(ad.pop()+&quot; &quot;);</div><div class="line">		&#125;</div><div class="line">		</div><div class="line">		System.out.println();</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<pre><code>输出：
Poping the stack: F E D B A 
</code></pre><p><strong>8.    EnumSet类</strong></p>
<pre><code>EnumSet扩展了AbstractSet类并实现了Set接口，专门用于枚举类型的元素。EnumSet是泛型类，其声明如下：

class EnumSet&lt;E extends EnumSet&lt;E&gt;&gt;

其中，E指定了元素。注意E必须扩展Enum&lt;E&gt;,这强制要求元素必须是指定的枚举类型。
</code></pre><p><strong>18.5 通过迭代器访问集合</strong></p>
<pre><code>迭代器是实现了Iterator或ListIterator接口的对象。Iterator接口允许遍历、获取或移除元素。ListIterator接口扩展了
Iterator接口，允许双向遍历列表，并且允许修改元素。Iterator和ListIterator是泛型接口，它们的声明如下：

interface Iterator&lt;E&gt;
interface ListIterator&lt;E&gt; 
</code></pre><ol>
<li><p>Iterator接口声明的方法：</p>
<p> void forEachRemainning(Consumer&lt;? super E&gt; action):对于集合中为处理的元素，执行action指定的动作(JDK 8 新增)<br> boolean hasNext():如果还有更多的元素，就返回true；否则返回false。<br> E next():返回下一个元素，如果不存在下一个元素，就抛出NoSuchElementException异常<br> void remove():移除当前元素。如果在调用next()方法之前试图调用remove()方法，就会抛出IllegalStateException异常</p>
</li>
<li><p>ListIterator接口声明的方法：</p>
<p> void add(E obj):将obj插入到列表中，新插入的元素位于下一次next()方法调用返回的元素之前。<br> void forEachRemainning(Consumer&lt;? super E&gt; action):对于集合中为处理的元素，执行action指定的动作(JDK 8 新增)<br> boolean hasNext():如果存在下一个元素，就返回true；否则返回false。<br> boolean hasPrevious():如果存在前一个元素，就返回true；否则返回false。<br> E next():返回下一个元素，如果不存在下一个元素，就抛出NoSuchElementException异常<br> int nextIndex():返回下一个元素的索引。如果不存在下一个元素，就返回列表的大小。<br> E previous():返回前一个元素。如果不存在前一个元素，就抛出NoSuchElementException异常<br> int previousIndex():返回前一个元素的索引。如果不存咋前一个元素，返回-1;<br> void remove():从列表中删除当前元素。如果在调用next()或previous()方法之前调用remove()方法，</p>
<pre><code>就会抛出IllegalStateException异常。
</code></pre><p> void set(E obj):将obj赋值给当前的元素，也就是next()或previous()方法调用最后返回的元素。</p>
</li>
</ol>
<p>注意： 从JDK 8开始，也可以使用Spliterator循环遍历集合。Spliterator的工作方式与Iterator不同，稍后将会详解。</p>
<p><strong>18.5.1 使用迭代器</strong></p>
<pre><code>为了能够通过迭代器访问集合，首先必须获得迭代器。每个集合类都提供了iterator()方法，该方法返回一个指向集合开头的迭代器。通过使用这个迭代器对象，可以访问集合中的每个元素，每次访问一个元素。通常为了使用迭代器遍历集合的内容，需要以下步骤：
(1)通过调用集合的iterator()方法，获取指向集合开头的迭代器。
(2)建立一个hasNext()方法调用循环。只要hasNext()返回true，就继续迭代。
(3)在循环中，通过调用next()方法获取每一个元素。

对于实现了List接口的集合可以调用listIterator()方法以获取迭代器。列表迭代器提供了向前和向后两个方向访问集合的能力，并且允许修改元素。除此之外，ListIterator与Iterator的用法类似。

例如：
</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div></pre></td><td class="code"><pre><div class="line">import java.util.*;</div><div class="line"></div><div class="line">class IteratorDemo</div><div class="line">&#123;</div><div class="line">	//Create an array list.</div><div class="line">	ArrayList&lt;String&gt; al = new ArrayList&lt;String&gt;();</div><div class="line">	</div><div class="line">	//Add elements to the array list.</div><div class="line">	al.add(&quot;C&quot;);</div><div class="line">	al.add(&quot;A&quot;);</div><div class="line">	al.add(&quot;E&quot;);</div><div class="line">	al.add(&quot;B&quot;);</div><div class="line">	al.add(&quot;D&quot;);</div><div class="line">	al.add(&quot;F&quot;);</div><div class="line">	</div><div class="line">	//Use iterator to display contents of al.</div><div class="line">	System.out.println(&quot;Original contents of al: &quot;);</div><div class="line">	Iterator&lt;String&gt; itr = al.iterator();</div><div class="line">	while(itr.hasNext())</div><div class="line">	&#123;</div><div class="line">		String element = itr.next();</div><div class="line">		System.out.print(element+&quot; &quot;);</div><div class="line">	&#125;</div><div class="line">	System.out.println();</div><div class="line">	</div><div class="line">	//Modify objects being iterated.</div><div class="line">	ListIterator&lt;String&gt; litr = al.listIterator();</div><div class="line">	while(litr.hasNext())</div><div class="line">	&#123;</div><div class="line">		String element = litr.next();</div><div class="line">		litr.set(element+&quot;+&quot;);</div><div class="line">	&#125;</div><div class="line">	</div><div class="line">	System.out.print(&quot;Modified contents of al: &quot;);</div><div class="line">	itr = al.iterator();</div><div class="line">	while(itr.hasNext())</div><div class="line">	&#123;</div><div class="line">		String element = itr.next();</div><div class="line">		System.out.print(element+&quot; &quot;);</div><div class="line">	&#125;</div><div class="line">	System.out.println();</div><div class="line">	</div><div class="line">	//Now,display the list backwards.</div><div class="line">	System.out.print(&quot;Modified list backwards: &quot;);</div><div class="line">	while(litr.hasPrevious())</div><div class="line">	&#123;</div><div class="line">		String element = litr.previous();</div><div class="line">		System.out.print(element+&quot; &quot;);</div><div class="line">	&#125;</div><div class="line">	System.out.println();</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<pre><code>输出：
Original contents of al: C A E B D F 
Modified contents of al: C+ A+ E+ B+ D+ F+
Modified list backwards: F+ D+ B+ E+ A+ C+
</code></pre><p><strong>18.5.2 使用for-each循环替代迭代器</strong></p>
<pre><code>如果不修改集合的内容，也不用反向获取元素，那么使用for-each风格的for循环遍历集合通常比使用迭代器更方便。请记住，可以使用for循环遍历任何实现了Iterator接口的集合对象。因为所有集合类都实现了这个接口。
</code></pre><p><strong>18.6 Spliterator</strong>  </p>
<pre><code>JDK 8新增了一种叫做spliterator的迭代器，这种迭代器有Spliterator接口定义。Spliterator用于循环遍历元素序列，在
这一点上与刚才介绍过的迭代器类似。但是，使用spliterator的方法与使用迭代器的不同。另外，它提供的功能远比
Iterator或ListIterator多。可能对于Spliterator来说，最重要的一点是它支持并行迭代序列的一部分。Spliterator支持
并行编程。然后，即使用不到并行编程，也可以使用Spliterator。这么做的一个理由是它将hasNext()和next()操作合并到
一个方法中，从而提高效率。

Spliterator是一个泛型接口，其声明如下所示：

interface Spliterator&lt;T&gt;

Spliterator接口声明的几个下面用到的方法：

default void forEachRemainning(Consumer&lt;? super T&gt; action):将action应用到数据源中未被处理的每一个元素。

boolean tryAdvance(Consumer&lt;? super T&gt; action)：
在迭代中的下一个元素上执行action。如果有下一个元素，就返回true；否则返回false；

将Spliterator用于基本迭代任务十分简单：只需要调用tryAdvance()方法，直到其返回false。如果要为序列中的每个元素应用相同的动作，forEachRemainning()提供了一种高效的替代方法。对于这两个方法，在每次迭代中将发生的动作都有
Consumer对象对每个元素执行的操作定义。Consumer是一个函数式接口，向对象应用了一个动作。他是java.util.function
中声明的一个泛型接口。Consumer仅指定了一个抽象方法accept()，如下所示：

void accept(R objRef)

对于tryAdvance()，每次迭代会将序列中的下一个元素传递个objRef。通常，实现Consumer最简单的方法是lambda表达式。

下面的程序给出了Spliterator的一个简单示例。注意，这个程序同时演示了tryAdvance()和forEachRemainning()。另外，还要注意这些方法如何把Iterator的next()和hasNext()方法操作到一个调用中：
</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div></pre></td><td class="code"><pre><div class="line">import java.util.*;</div><div class="line"></div><div class="line">class SpliteratorDemo</div><div class="line">&#123;</div><div class="line">	public static void main(String[] args)</div><div class="line">	&#123;</div><div class="line">		//Create an array list for doubles.</div><div class="line">		ArrayList&lt;Double&gt; vals = new ArrayList&lt;&gt;();</div><div class="line">		</div><div class="line">		vals.add(1.0);</div><div class="line">		vals.add(2.0);</div><div class="line">		vals.add(3.0);</div><div class="line">		vals.add(4.0);</div><div class="line">		vals.add(5.0);</div><div class="line">		</div><div class="line">		//Use tryAdvance() to display contents of vals.</div><div class="line">		System.out.println(&quot;Contents of vals: &quot;);</div><div class="line">		Spliterator spltitr = vals.spliterator();</div><div class="line">		while(spltitr.tryAdvance((n) -&gt; System.out.println(n)));</div><div class="line">		System.out.println();</div><div class="line">		</div><div class="line">		//Create new list that contains square roots.</div><div class="line">		spltitr = vals.spliterator();</div><div class="line">		ArrayList&lt;Double&gt; sqrs = new ArrayList&lt;&gt;();</div><div class="line">		while(spltitr.tryAdvance((n) -&gt; sqrs.add(Math.sqrt(n))));</div><div class="line">		</div><div class="line">		//Use forEachRemainning() to display contents of sqrs.</div><div class="line">		System.out.println(&quot;Contents of sqrs: &quot;);</div><div class="line">		spltitr = sqrs.spliterator();</div><div class="line">		spltitr.forEachRemainning((n) -&gt; System.out.println(n));</div><div class="line">		System.out.println();</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<pre><code>输出：
Contents of vals:
1.0
2.0
3.0
4.0
5.0

Contents of sqrs:
1.0
1.414...
1.732...
2.0
2.236...

虽然这个程序演示了Spliterator的原理，却没有展现其强大的能力。如前所述，在涉及并行处理的地方，Spliterator的最大优势才能体现出来。
</code></pre><p><strong>18.9 使用映射</strong></p>
<pre><code>映射是存储键和值之间关联关系(键值对)的对象。给定一个键，就可以找到对应的值。键和值都是对象。键必须唯一，但是只可以重复。某些映射可以接受null键和null值，其他映射则不能。

关于映射需要注意的关键一点是：它们没有实现Iterator接口。这意味着不能使用for-each风格的for循环遍历映射。此外，不能为映射获取迭代器。但是，正如即将看到的，可以获取映射的集合视图，集合视图允许使用for循环和迭代器。
</code></pre><p><strong>18.9.1 映射接口</strong></p>
<pre><code>支持映射的接口有Map、Map.Entry、NavigableMap和SortedMap。
</code></pre><p><strong>1.    Map接口</strong></p>
<pre><code>Map接口将唯一键映射到值。键是以后用于检索值的对象。给定键和值，可以在Map对象中存储值；存储值以后，可以使用相应的键检索值。Map是泛型接口，其声明如下：

interface Map&lt;K,V&gt;

其中，K指定了键的类型，V指定了值的类型。

映射围绕两个基本方法：get()和put()。为了将值放入映射中，使用put()方法，指定键和值。为了获取值，调用get()方法，传递键作为参数，值会被返回。

尽管映射是集合框架的一部分，但映射不是集合，因为没有实现Collections接口。但是，可以获取映射的集合视图。为此，可以使用entrySet()方法。该方法返回一个包含映射中元素的Set对象。为了获取键的集合视图，使用keySet()方法；为了得到值的集合视图，使用values()方法。对于这3个集合视图，集合都是基于映射的。修改其中的一个集合会影响其他集合。集合视图是将映射集成到更大集合框架中的手段。
</code></pre><p><strong>2.    SortedMap接口</strong></p>
<pre><code>SortedMap接口扩展了Map接口，确保条目以键的升序保存。SortedMap是泛型接口，其声明如下：

interface SortedMap&lt;K,V&gt;
</code></pre><p><strong>3.    NavigableMap接口</strong></p>
<pre><code>NavigableMap接口扩展了SortedMap接口，支持基于最接近匹配原则的条目的检索行为，即支持检索与给定的一个或多个键最相匹配的条目。NavigableMap是泛型接口，其声明如下：

interface NavigableMap&lt;K,V&gt;
</code></pre><p><strong>4.    Map.Entry接口</strong></p>
<pre><code>Map.Entry接口提供了操作映射条目的功能。请记住，Map接口声明的entrySet()方法返回一个包含映射条目的Set对象。组的所有元素都是Map.Entry对象。Map.Entry是泛型接口，起声明如下：

interface Map.Entry&lt;K,V&gt;
</code></pre><p><strong>18.9.2 映射类</strong></p>
<pre><code>AbstractMap:实现了Map接口的大部分
HashMap：扩展了AbstractMap，以使用哈希表
TreeMap：扩展了AbstractMap，以使用树结构
LinkedHashMap：扩展了HashMap，以允许按照插入顺序进行迭代
EnumMap：扩展了AbstractMap，以使用enum键
WeekHashMap:扩展了AbstractMap，以使用带有弱键的哈希表
IdentityHashMap:扩展了AbstractMap，并且当比较文档时使用引用相等性

注意AbstractMap是所有具体映射实现的超类。
</code></pre><p><strong>1.    HashMap类</strong></p>
<pre><code>HashMap扩展了AbstractMap类并实现了Map接口。它使用哈希表存储映射，这使得即使对于比较大的集合，get()和put()方法的执行时间也保持不变。

应当注意哈希映射不保证元素的顺序。所以，向哈希映射添加元素的顺序不一定是通过迭代器读取它们的顺序。

下面的程序演示了HashMap，将名字映射的账户金额。注意获取和使用组视图的方式：
</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div></pre></td><td class="code"><pre><div class="line">import java.util.*;</div><div class="line"></div><div class="line">class HashMapDemo</div><div class="line">&#123;</div><div class="line">	public static void main(String[] args)</div><div class="line">	&#123;</div><div class="line">		HashMap&lt;String,Double&gt; hm = new HashMap&lt;&gt;();</div><div class="line">		</div><div class="line">		hm.put(&quot;John Doe&quot;,new Double(3434.34));</div><div class="line">		hm.put(&quot;Tom Smith&quot;,new Double(123.22));</div><div class="line">		hm.put(&quot;Jane Baker&quot;,new Double(1378.00));</div><div class="line">		hm.put(&quot;Tod Hall&quot;,new Double(99.22));</div><div class="line">		hm.put(&quot;Ralph Smith&quot;,new Double(-19.08));</div><div class="line">		</div><div class="line">		//Get a set of the entries.</div><div class="line">		Set&lt;Map.Entry&lt;String,Double&gt;&gt; set = hm.entrySet();</div><div class="line">		</div><div class="line">		//Display the set.</div><div class="line">		for(Map.Entry&lt;String,Double&gt; me:set)</div><div class="line">		&#123;</div><div class="line">			System.out.print(me.getKey()+&quot;;&quot;)</div><div class="line">			System.out.println(me.getValue());</div><div class="line">		&#125;</div><div class="line">		</div><div class="line">		System.out.println();</div><div class="line">		</div><div class="line">		//Deposit 1000 into John Doe&apos;s account.</div><div class="line">		double balance = hm.get(&quot;John Doe&quot;);</div><div class="line">		hm.put(&quot;John Doe&quot;,balance+1000);</div><div class="line">		</div><div class="line">		System.out.println(&quot;John Doe&apos;s new balance: &quot;+hm.get(&quot;John Doe&quot;));</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<pre><code>输出(精确的顺序可能会有所变化)：
Ralph Smith: -19.08 
Tom Smith: 123.22
John Doe: 3434.34
Tod Hall: 99.22
Jane Baker: 1378.0 

John Doe&apos;s new balance: 4434.34
</code></pre><p><strong>2. TreeMap类</strong></p>
<pre><code>TreeMap扩展了AbstractMap类并实现了NavigableMap接口，该类用于创建存储在树结构中的映射。TreeMap提供了有序存储键/值对的高效手段，并支持快速检索。应当注意，与哈希映射不同，树映射确保元素以键的升序存储。

下面的程序对前面的程序进行了修改，以使用TreeMap类：
</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div></pre></td><td class="code"><pre><div class="line">import java.util.*;</div><div class="line"></div><div class="line">class TreeMapDemo</div><div class="line">&#123;</div><div class="line">	public static void main(String[] args)</div><div class="line">	&#123;</div><div class="line">		TreeMap&lt;String,Double&gt; tm = new TreeMap&lt;&gt;();</div><div class="line">		</div><div class="line">		tm.put(&quot;John Doe&quot;,new Double(3434.34));</div><div class="line">		tm.put(&quot;Tom Smith&quot;,new Double(123.22));</div><div class="line">		tm.put(&quot;Jane Baker&quot;,new Double(1378.00));</div><div class="line">		tm.put(&quot;Tod Hall&quot;,new Double(99.22));</div><div class="line">		tm.put(&quot;Ralph Smith&quot;,new Double(-19.08));</div><div class="line">		</div><div class="line">		Set&lt;Map.Entry&lt;String,Double&gt;&gt; set = tm.entrySet();</div><div class="line">		</div><div class="line">		for(Map.Entry&lt;String,Double&gt; me : set)</div><div class="line">		&#123;</div><div class="line">			System.out.print(me.getKey()+&quot;:&quot;);</div><div class="line">			System.out.println(me.getValue());</div><div class="line">		&#125;</div><div class="line">		</div><div class="line">		System.out.println();</div><div class="line">		</div><div class="line">		//Deposit 1000 into John Doe&apos;s account.</div><div class="line">		double balance = tm.get(&quot;John Doe&quot;);</div><div class="line">		tm.put(&quot;John Doe&quot;,balance+1000);</div><div class="line">		</div><div class="line">		System.out.println(&quot;John Doe&apos;s new balance: &quot;+tm.get(&quot;John Doe&quot;));</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<pre><code>输出：
Jane Baker: 1378.0 
John Doe: 3434.34
Ralph Smith: -19.08 
Tod Hall: 99.22
Tom Smith: 123.22

John Doe&apos;s new balance: 4434.34

注意TreeMap对键进行排序，然而这个例子中，它们根据名(first name)而不是姓(last name)进行排序。正如稍后描述的，在创建映射时，可以通过指定比较器来改变这种行为。
</code></pre><p><strong>3.    LinkedHashMap类</strong></p>
<pre><code>LinkedHashMap扩展了HashMap，在映射中以插入条目的顺序维护一个条目链表，从而可以按照插入顺序迭代整个映射。

也就是说，当遍历LinkedHashMap的集合视图时，将以元素的插入顺序返回元素。也可以创建按照最后访问的顺序返回元素的LinkedHashMa。
</code></pre><p><strong>18.10    比较器</strong> </p>
<pre><code>TreeSet和TreeMap类以有序顺序存储元素。然而，是比较器精确定义了&quot;有序顺序&quot;的含义。默认情况下，这些类使用Java称为&quot;自然顺序&quot;的方式对元素进行排序，自然顺序通常是你所期望的顺序(A在B之前，1在2之前，等等)。如果希望以不同的方式排序元素，可以在构造函组或映射时指定比较器，这样就可以精确控制在有序集合和映射中存储元素的方式。

Comparator是泛型接口，其声明如下：

interface Comparator&lt;T&gt;

在JDK 8之前，Comparator接口只定义了两个方法：compare()和equals()。
compare()方法如下所示，用于比较两个元素以进行排序：

int compare(T obj1,T obj2)

obj1和obj2是要进行比较的对象。在正常情况下，如果对象相等，该方法返回0；如果obj1大于obj2，返回一个正值，反之，返回一个负值。如果要进行比较的对象的类型不兼容，该方法会抛出ClassCastException异常。通过实现compare()方法，可以改变对象的排序方式。例如，为了按照相反的顺序进行排序，可以创建比较器以反转比较的结果。

equals()方法如下所示，用于测试某个对象是否等于比较器：

boolean equals(object obj)

其中，obj是将要进行相等测试的对象。如果obj和调用对象都是比较器，并且使用相同的排序规则，那么该方法返回true；
否则，返回false。不必重写equals()方法，并且大多数简单的比较器都不重写该方法。

在JDK 8后，通过使用默认接口方法和静态接口方法，JDK 8为Comparator添加了许多新功能。下面逐一进行介绍。

通过reserved()方法，可以获得一个比较器，该比较器颠倒了调用reserved()的比较器的排序：

default Comparator&lt;T&gt; reserved()

该方法返回一个颠倒的比较器。

reserseOrder()是与reserve()关联的一个方法，如下所示：

static &lt;T extends Comparable&lt;? super T&gt;&gt; Comparator&lt;T&gt; reserseOrder()

它返回一个颠倒元素的自然顺序的比较器。对应的，通过调用静态的naturalOrder()方法，可以获得一个使用自然顺序的比较器。该方法声明如下所示：

static &lt;T extends Comparable&lt;? super T&gt;&gt; Comparator&lt;T&gt; natualOrder()

如果希望比较器能够处理null值，需要使用下面的nullsFirst()和nullsLast()方法：

static &lt;T&gt; Comparator&lt;T&gt; nullsFirst(Comparator&lt;? super T&gt; comp)
static &lt;T&gt; Comparator&lt;T&gt; nullsLast(Comparator&lt;? super T&gt; comp)

nullsFirst()方法返回的比较器认为null比其他值小，nullLast()方法返回的比较器认为null比其他值大。对于这两个方法，如果被比较的两个值都是非null值，则comp执行比较。如果为comp赋值null，则认为所有非null值都是相等的。

JDK 8添加的另一个默认方法是thenComparing()。该方法返回一个比较器，当第一次比较的结果指出被比较的结果相等时，
返回的这个比较器将执行第二次比较。因此，可以使用该方法创建一个&quot;根据X比较，然后根据Y比较&quot;的序列。例如，当比较城市时，第一次可能比较城市名，第二次可能比较州名。如果城市名相同，则在比较州名。

thenComparing()方法有三种形式。
第一种形式如下所示：它允许通过传入Comparator的实例来指定第二个比较器。

default Comparator&lt;T&gt; thenComparing(Comparator&lt;? super T&gt; thenByComp)

其中，thenByComp指定在第一次比较返回相等后调用的比较器。

thenComparing()的另外两个版本允许指定标准函数式接口Function，如下所示：

default &lt;U extends Comparator&lt;? super U&gt;&gt; Comparator&lt;T&gt; 
    thenComparing(Function&lt;? super T,? extends U&gt; getKey)

default &lt;U extends Comparator&lt;? super U&gt;&gt; Comparator&lt;T&gt; 
    thenComparing(Function&lt;? super T,? extends U&gt; getKey,Comparator&lt;? super U&gt; keyComp)

在这两个版本中，getKey引用的函数用于获得下一个比较键，当第一次比较返回相等后，将使用这个比较键。后一个版本中的keyComp指定了用于比较键的比较器(U指定了键的类型)。
</code></pre><p>使用比较器：</p>
<pre><code>下面演示了一个自定义比较器功能的例子。该例为字符串实现了compare()方法，以与正常顺序相反的顺序进行操作。因此，这将导致树组(tree set)以相反的顺序进行存储。
</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div></pre></td><td class="code"><pre><div class="line">import java.util.*;</div><div class="line"></div><div class="line">class MyComp implements Comparator&lt;String&gt;</div><div class="line">&#123;</div><div class="line">	public int compare(String aStr,String bStr)</div><div class="line">	&#123;</div><div class="line">		//Reverse the comparison</div><div class="line">		return bStr.compareTo(aStr);</div><div class="line">	&#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line">class CompDemo</div><div class="line">&#123;</div><div class="line">	public static void main(String[] args)</div><div class="line">	&#123;</div><div class="line">		TreeSet&lt;String&gt; ts = new TreeSet&lt;&gt;(new MyComp());</div><div class="line">		</div><div class="line">		ts.add(&quot;C&quot;);</div><div class="line">		ts.add(&quot;A&quot;);</div><div class="line">		ts.add(&quot;B&quot;);</div><div class="line">		ts.add(&quot;E&quot;);</div><div class="line">		ts.add(&quot;F&quot;);</div><div class="line">		ts.add(&quot;D&quot;);</div><div class="line">		</div><div class="line">		for(String element : ts)</div><div class="line">		&#123;</div><div class="line">			System.out.print(element+&quot; &quot;);</div><div class="line">		&#125;</div><div class="line">		</div><div class="line">		System.out.println();</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<pre><code>输出：
F E D C B A 


尽管上面的程序实现逆序比较器的方法完全可以接受，但是从JDK8开始，还有另外一种方法可以获得解决方案。
即，现在可以简单的对自然顺序比较器调用reversed()方法。该方法返回一个等价的比较器，不过比较器的顺序是相反的。
例如，在前面的程序中，可以把MyComp重写为自然顺序的比较器，如下所示：
</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">class MyComp implements Comparator&lt;String&gt;</div><div class="line">&#123;</div><div class="line">	public int compare(String aStr,String bStr)</div><div class="line">	&#123;</div><div class="line">		return aStr.compareTo(bStr);</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<pre><code>然后，可以使用下面的代码段创建一个反向排序字符串元素的TreeSet:

MyComp mc = new MyComp();

TreeSet&lt;String&gt; ts = new TreeSet&lt;&gt;(mc.reserved());

如果把这段新代码放到前面的程序中，得到的结果与原来的一样。在这个例子中，使用reversed()方法没有什么优势。但是，当需要同时创建自然顺序和反向顺序的比较器时，使用reversed()方法能够方便的获得逆序比较器，而不需要显示对其编码。

从JDK 8开始，在前面的例子中，实际上没有必要创建MyComp类，因为可以很方便的使用lambda表达式作为替代。
例如，可以彻底删除MyComp类，使用下面的代码创建字符串比较器:

Comparator&lt;String&gt; mc = (aStr,bStr)-&gt;aStr.compareTo(bStr);

另外还有一点：在这个简单的示例中，通过使用lambda表达式，可以在对TreeSet()构造函数的调用中直接指定逆序比较器，如下所示：

TreeSet&lt;String&gt; ts = new TreeSet&lt;&gt;((aStr,bStr) -&gt; bStr.compareTo(aStr));

做了上述修改后，程序得以显著缩短。下面显示了最终版本：
</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div></pre></td><td class="code"><pre><div class="line">import java.util.*;</div><div class="line"></div><div class="line">class CompDemo2</div><div class="line">&#123;</div><div class="line">	public static void main(String[] args)</div><div class="line">	&#123;</div><div class="line">		TreeSet&lt;String&gt; ts = new TreeSet&lt;&gt;((aStr,bStr) -&gt; bStr.compareTo(aStr));</div><div class="line">		</div><div class="line">		ts.add(&quot;C&quot;);</div><div class="line">		ts.add(&quot;A&quot;);</div><div class="line">		ts.add(&quot;B&quot;);</div><div class="line">		ts.add(&quot;E&quot;);</div><div class="line">		ts.add(&quot;F&quot;);</div><div class="line">		ts.add(&quot;D&quot;);</div><div class="line">		</div><div class="line">		for(String element : ts)</div><div class="line">		&#123;</div><div class="line">			System.out.print(element+&quot; &quot;);</div><div class="line">		&#125;</div><div class="line">		</div><div class="line">		System.out.println();</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<pre><code>作为使用自定义比较器的更实际的例子，下面的程序是前面显示的存储账户余额的TreeMap程序的升级版。在前面的版本中，账户根据名字进行存储，但排序是从名开始的。下面的程序根据姓对账户进行排序。为此，使用比较器比较每个账户的姓，这会使得映射根据姓进行排序。
</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div></pre></td><td class="code"><pre><div class="line">import java.util.*;</div><div class="line"></div><div class="line">class TComp implements Comparator&lt;String&gt;</div><div class="line">&#123;</div><div class="line">	public int compare(String aStr,String bStr)</div><div class="line">	&#123;</div><div class="line">		int i,j,k;</div><div class="line">		</div><div class="line">		i = aStr.lastIndexOf(&apos; &apos;);</div><div class="line">		j = bStr.lastIndexOf(&apos; &apos;);</div><div class="line">		</div><div class="line">		k = aStr.subString(i).compareToIgnoreCase(bStr.subString(j));</div><div class="line">		if(k == 0)	//last name match,check entire name</div><div class="line">		&#123;</div><div class="line">			return aStr.compareToIgnoreCase(bStr);</div><div class="line">		&#125;</div><div class="line">		else</div><div class="line">		&#123;</div><div class="line">			return k;</div><div class="line">		&#125;</div><div class="line">		</div><div class="line">	&#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line">class TreeMapDemo2</div><div class="line">&#123;</div><div class="line">	public static void main(String[] args)</div><div class="line">	&#123;</div><div class="line">		TreeMap&lt;String,Double&gt; tm = new TreeMap&lt;&gt;(new TComp());</div><div class="line">		</div><div class="line">		tm.put(&quot;John Doe&quot;,new Double(3434.34));</div><div class="line">		tm.put(&quot;Tom Smith&quot;,new Double(123.22));</div><div class="line">		tm.put(&quot;Jane Baker&quot;,new Double(1378.00));</div><div class="line">		tm.put(&quot;Tod Hall&quot;,new Double(99.22));</div><div class="line">		tm.put(&quot;Ralph Smith&quot;,new Double(-19.08));</div><div class="line">		</div><div class="line">		Set&lt;Map.Entry&lt;String,Double&gt;&gt; set = tm.entrySet();</div><div class="line">		</div><div class="line">		for(Map.Entry&lt;String,Double&gt; me : set)</div><div class="line">		&#123;</div><div class="line">			System.out.print(me.getKey()+&quot;:&quot;);</div><div class="line">			System.out.println(me.getValue());</div><div class="line">		&#125;</div><div class="line">		</div><div class="line">		System.out.println();</div><div class="line">		</div><div class="line">		//Deposit 1000 into John Doe&apos;s account.</div><div class="line">		double balance = tm.get(&quot;John Doe&quot;);</div><div class="line">		tm.put(&quot;John Doe&quot;,balance+1000);</div><div class="line">		</div><div class="line">		System.out.println(&quot;John Doe&apos;s new balance: &quot;+tm.get(&quot;John Doe&quot;));</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<pre><code>输出：
Jane Baker: 1378.0 
John Doe: 3434.34
Tod Hall: 99.22
Ralph Smith: -19.08     
Tom Smith: 123.22

John Doe&apos;s new balance: 4434.34

比较器类TComp比较包含名和姓的两个字符串。该类首先比较姓，如果姓相同的话，在根据名进行排序。

如果使用的是JDK 8或更高版本，还有另一种方法来编码前面的程序，让映射首先根据姓进行排序，然后根据名进行排序。
这会用到thenComparing()方法。回忆一下，thenComparing()允许指定第二个比较器，当调用比较器返回相等时，就会使用第二个比较器。下面的程序演示了这种方法，它修改了前面的程序，使之使用thenComparing()方法。 
</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div></pre></td><td class="code"><pre><div class="line">import java.util.*;</div><div class="line"></div><div class="line">//A comparator that compares last names.</div><div class="line">class CompLastNames implements Comparator&lt;String&gt;</div><div class="line">&#123;</div><div class="line">	public int compare(String aStr,String bStr)</div><div class="line">	&#123;</div><div class="line">		int i,j;</div><div class="line">	</div><div class="line">		i = aStr.lastIndexOf(&apos; &apos;);</div><div class="line">		j = bStr.lastIndexOf(&apos; &apos;);</div><div class="line">	</div><div class="line">		return aStr.subString(i).compareToIgnoreCase(bStr.subString(j));</div><div class="line">	&#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line">//Sort by entire name when last names are equals.</div><div class="line">class CompThenByFirstName implements Comparator&lt;String&gt;</div><div class="line">&#123;</div><div class="line">	public int compare(String aStr,String bStr)</div><div class="line">	&#123;			</div><div class="line">		return aStr.compareToIgnoreCase(bStr);</div><div class="line">	&#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line">class TreeMapDemo2A</div><div class="line">&#123;</div><div class="line">	public static void main(String[] args)</div><div class="line">	&#123;</div><div class="line">		CompLastNames compLN = new CompLastNames();</div><div class="line">		Comparator&lt;String&gt; compLastThenFirst = compLN.thenComparing(new CompThenByFirstName());</div><div class="line">		</div><div class="line">		TreeMap&lt;String,Double&gt; tm = new TreeMap&lt;&gt;(compLastThenFirst);</div><div class="line">		</div><div class="line">		tm.put(&quot;John Doe&quot;,new Double(3434.34));</div><div class="line">		tm.put(&quot;Tom Smith&quot;,new Double(123.22));</div><div class="line">		tm.put(&quot;Jane Baker&quot;,new Double(1378.00));</div><div class="line">		tm.put(&quot;Tod Hall&quot;,new Double(99.22));</div><div class="line">		tm.put(&quot;Ralph Smith&quot;,new Double(-19.08));</div><div class="line">		</div><div class="line">		Set&lt;Map.Entry&lt;String,Double&gt;&gt; set = tm.entrySet();</div><div class="line">		</div><div class="line">		for(Map.Entry&lt;String,Double&gt; me : set)</div><div class="line">		&#123;</div><div class="line">			System.out.print(me.getKey()+&quot;:&quot;);</div><div class="line">			System.out.println(me.getValue());</div><div class="line">		&#125;</div><div class="line">		</div><div class="line">		System.out.println();</div><div class="line">		</div><div class="line">		//Deposit 1000 into John Doe&apos;s account.</div><div class="line">		double balance = tm.get(&quot;John Doe&quot;);</div><div class="line">		tm.put(&quot;John Doe&quot;,balance+1000);</div><div class="line">		</div><div class="line">		System.out.println(&quot;John Doe&apos;s new balance: &quot;+tm.get(&quot;John Doe&quot;));</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<pre><code>这个版本产生的输入与原来的版本相同，二者唯一的区别在于完成的工作方法。

最后，注意为了清晰起见，本例显示创建了两个比较器类CompLastNames和ComThenByFirstName，但是其实也可以使用
lambda表达式。例如：
</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line">Comparator&lt;String&gt; compLastName = (aStr,bStr)-&gt;</div><div class="line">   &#123;</div><div class="line">       int i,j;</div><div class="line"></div><div class="line">       i = aStr.lastIndexOf(&apos; &apos;);</div><div class="line">       j = bStr.lastIndexOf(&apos; &apos;);</div><div class="line"></div><div class="line">       return aStr.substring(i).compareToIgnoreCase(bStr.substring(j));</div><div class="line">   &#125;;</div><div class="line"></div><div class="line">   Comparator&lt;String&gt; compThenFirstName = (aStr,bStr)-&gt;aStr.compareToIgnoreCase(bStr);</div><div class="line"></div><div class="line">   Comparator&lt;String&gt; comp = compLastName.thenComparing(compThenFirstName);</div><div class="line"></div><div class="line">   TreeMap&lt;String,Double&gt; tm = new TreeMap&lt;&gt;(comp);</div></pre></td></tr></table></figure>
<p><strong>18.11 集合算法</strong></p>
<pre><code>集合框架定义了一些可以应用于集合和映射的算法，这些算法被定义为Collections类中的静态方法中，可以自行查看
Collections类的源码查看这些函数。

注意有些方法用于获取各种集合的同步(线程安全的)副本，例如synchronizedList()和synchronizedSet()。作为一般规则
，标准集合实现不是同步的。必须使用同步算法提供同步。另外一点：同步集合的迭代器必须在synchronized代码块中使用

以unmodifiable开始的一组方法集返回各种不能修改的集合视图。如果希望确保对集合进行某些读取操作——但是不允许写入操作，这些方法是有用的。

下面的程序演示了一些算法，创建并初始化一个链表。reverseOrder()方法返回翻转Integer对象比较结果的比较器。列表元素根据这个比较器进行排序，然后显示。接下来，调用shuffle()方法以随机化链表，然后显示链表中的最大值和最小值
</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div></pre></td><td class="code"><pre><div class="line">import java.util.*;</div><div class="line"></div><div class="line">class AlgorithmsDemo</div><div class="line">&#123;</div><div class="line">	public static void main(String[] args)</div><div class="line">	&#123;</div><div class="line">		LinkedList&lt;Integer&gt; ll = new LinkedList&lt;Integer&gt;();</div><div class="line">		ll.add(-8);</div><div class="line">		ll.add(20);</div><div class="line">		ll.add(-20);</div><div class="line">		ll.add(8);</div><div class="line">		</div><div class="line">		//Create a reserve order comparator.</div><div class="line">		Comparator&lt;Integer&gt; r = Collections.reserseOrder();</div><div class="line">		</div><div class="line">		//Sort list by using the comparator.</div><div class="line">		Collections.sort(ll,r);</div><div class="line">		</div><div class="line">		System.out.print(&quot;List sorted in reverse: &quot;);</div><div class="line">		for(int i : ll)</div><div class="line">		&#123;</div><div class="line">			System.out.print(i+&quot; &quot;);</div><div class="line">		&#125;</div><div class="line">		</div><div class="line">		System.out.println();</div><div class="line">		</div><div class="line">		//Shuffle list.</div><div class="line">		Collections.shuffle(ll);</div><div class="line">		</div><div class="line">		//Display randomized list.</div><div class="line">		System.out.print(i+&quot; &quot;);</div><div class="line">		</div><div class="line">		System.out.println();</div><div class="line">		System.out.println(&quot;Mininum: &quot;+Collections.min(ll));</div><div class="line">		System.out.println(&quot;Maxinum: &quot;+Collections.max(ll));</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<pre><code>输出：
List sorted in reserve: 20 8 -8 -20 
List shuffled: 20 -20 8 -8 
Mininum: -20 
Maxinum: 20 

注意是在随机化后，才对链表进行min()和max()操作的。这两个方法的操作都不要求列表是排序过的。
</code></pre><p><strong>18.12    Arrays类</strong></p>
<pre><code>Arrays类提供了对数组操作有用的方法，这些方法有助于连接集合和数组。

asList()方法返回基于指定数组的列表。
static &lt;T&gt; List asList(T ...array)
其中，array是包含数据的数组。

binarySeach()方法使用二分搜索法查找特定数值。

copyOf()方法返回数组的副本。

copyOfRange()方法返回数组中某个范围的副本。

fill()方法可以将某个值赋给数组中的所有元素。

sort()方法用于对数组进行排序。

JDK 8为Arrays类添加了一些新的方法，其中最重要的可能是parallelSort()方法，因为该方法按升序对数组的各部分
进行并行排序，然后合并结果。这种方法可以显著加速排序时间。

通过包含spliterator()方法，JDK 8为Arrays类添加了对spliterator的支持。该方法有两种基本形似。
第一种版本返回整个数组的spliterator,如下所示： 

static&lt;T&gt; Spliterator spliterator(T array[])

这里，array是spliterator将循环遍历的数组。第二种版本的spliterator()方法允许指定希望进行迭代的数组范围。

从JDK 8开始，通过包含stream()方法，Arrays类支持新的Stream接口。stream()方法有两个版本，下面显示了第一个
版本：

static&lt;T&gt; Stream stream(T array[])

这里，array是流将引用的数组。第二种版本的stream()方法允许指定数组内的一个范围。

除了刚才讨论的方法，JDK 8还添加了另外3个新方法。其中两个彼此相关：setAll()和parallelSetAll()。这两个方法
都是为所有元素赋值，但是parallelSetAll()以并行方式工作。

最后JDK 8还为Arrays类添加了一个有意思的方法：parallelPrefix().该方法对数组进行修改，使每个元素都包含对其
前面所有元素应用某个操作的累积结果。


下面演示了如何使用Arra类的一些方法：
</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div></pre></td><td class="code"><pre><div class="line">import java.util.*;</div><div class="line"></div><div class="line">class ArraysDemo</div><div class="line">&#123;</div><div class="line">	public static void main(String[] args)</div><div class="line">	&#123;</div><div class="line">		//Allocate and initialize array.</div><div class="line">		int[] array = new int[10];</div><div class="line">		for(int i=0; i&lt;10; i++)</div><div class="line">		&#123;</div><div class="line">			array[i] = -3*i;</div><div class="line">		&#125;</div><div class="line">		</div><div class="line">		//Display,sort,and display the array.</div><div class="line">		System.out.print(&quot;Original contents: &quot;);</div><div class="line">		display(array);</div><div class="line">		Arrays.sort(array);</div><div class="line">		System.out.print(&quot;Sorted: &quot;);</div><div class="line">		display(array);</div><div class="line">		</div><div class="line">		//Fill and display the array.</div><div class="line">		Arrays.fill(array,2,6,-1);</div><div class="line">		System.out.print(&quot;After fill(): &quot;);</div><div class="line">		display(array);</div><div class="line">		</div><div class="line">		//Sorted and display the array.</div><div class="line">		Arrays.sort(array);</div><div class="line">		System.out.println(&quot;After sorting again: &quot;);</div><div class="line">		display(array);</div><div class="line">		</div><div class="line">		//Binary seach for -9;</div><div class="line">		System.out.print(&quot;The value -9 is at location: &quot;);</div><div class="line">		int index = Arrays.binarySeach(array,-9);</div><div class="line">		System.out.println(index);</div><div class="line">	&#125;</div><div class="line">	</div><div class="line">	static void display(int[] array)</div><div class="line">	&#123;</div><div class="line">		for(int i : array)</div><div class="line">		&#123;</div><div class="line">			System.out.print(i+&quot; &quot;);</div><div class="line">		&#125;</div><div class="line">		</div><div class="line">		System.out.println();</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<pre><code>输出：
Original contents: 0 -3 -6 -9 -12 -15 -18 -21 -24 -27
Sorted: -27 -24 -21 -18 -15 -12 -9 -6 -3 -0 
After fill(): -27 -24 -1 -1 -1 -1 -9 -6 -3 0
After sorting again: -27 -24 -9 -6 -3 -1 -1 -1 -1 0
The value -9 is at location: 2
</code></pre><p><strong>18.13    遗留的类和接口</strong></p>
<pre><code>在本章开头解释过，早期版本的java.util包没有包含集合框架，而是定义了几个类和一个接口，用来提供存储对象的专业方法。

本章介绍的所有现代集合类都不是同步的，但是所有遗留类都是同步的，有些情况这一差别很重要。当然，通过使用
Collections提供的算法，可以很容易的同步集合。

java.util定义的遗留类如下所示：
Dictionary    Hashtable    Properies    Stack    Vector 
还有遗留接口Enumeration.

此处，就介绍遗留类和接口的介绍了。
</code></pre><p>出自：《Java 8编程参考官方教程(第9版)》</p>
</the>
      
    </div>
    
  </div>
  
    
    <div class="copyright">
        <p><span>本文标题:</span><a href="/Programming/Java/Java之集合框架/">Java之集合框架</a></p>
        <p><span>文章作者:</span><a href="/" title="回到主页">FreeShow</a></p>
        <p><span>发布时间:</span>2016-07-23, 23:03:47</p>
        <p><span>最后更新:</span>2017-03-28, 16:06:22</p>
        <p>
            <span>原始链接:</span><a class="post-url" href="/Programming/Java/Java之集合框架/" title="Java之集合框架">https://freeshow.github.io/Programming/Java/Java之集合框架/</a>
            <span class="copy-path" data-clipboard-text="原文: https://freeshow.github.io/Programming/Java/Java之集合框架/　　作者: FreeShow" title="点击复制文章链接"><i class="fa fa-clipboard"></i></span>
            <script> var clipboard = new Clipboard('.copy-path'); </script>
        </p>
        <p>
            <span>许可协议:</span><i class="fa fa-creative-commons"></i> <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/" title="CC BY-NC-SA 4.0 International" target = "_blank">"署名-非商用-相同方式共享 4.0"</a> 转载请保留原文链接及作者。
        </p>
    </div>



    <nav id="article-nav">
        
            <div id="article-nav-newer" class="article-nav-title">
                <a href="/Programming/Java/Java之字符串处理/">
                    Java之字符串处理
                </a>
            </div>
        
        
            <div id="article-nav-older" class="article-nav-title">
                <a href="/Programming/Scala/Scala访问控制修饰符/">
                    Scala访问控制修饰符
                </a>
            </div>
        
    </nav>

  
</article>

    <div id="toc" class="toc-article">
        <strong class="toc-title">文章目录</strong>
        
            
        
    </div>
    <style>
        .left-col .switch-btn,
        .left-col .switch-area {
            display: none;
        }
        .toc-level-3 i,
        .toc-level-3 ol {
            display: none !important;
        }
    </style>

    <input type="button" id="tocButton" value="隐藏目录"  title="点击按钮隐藏或者显示文章目录">

    <script>
        yiliaConfig.toc = ["隐藏目录", "显示目录", !!"false"];
    </script>



    
<div class="share">
    
        <div class="bdsharebuttonbox">
            <a href="#" class="fa fa-twitter bds_twi" data-cmd="twi" title="分享到推特"></a>
            <a href="#" class="fa fa-weibo bds_tsina" data-cmd="tsina" title="分享到新浪微博"></a>
            <a href="#" class="fa fa-qq bds_sqq" data-cmd="sqq" title="分享给 QQ 好友"></a>
            <a href="#" class="fa fa-files-o bds_copy" data-cmd="copy" title="复制网址"></a>
            <a href="#" class="fa fa fa-envelope-o bds_mail" data-cmd="mail" title="通过邮件分享"></a>
            <a href="#" class="fa fa-weixin bds_weixin" data-cmd="weixin" title="生成文章二维码"></a>
            <a href="#" class="fa fa-share-alt bds_more" data-cmd="more"></i></a>
        </div>
        <script>
            window._bd_share_config={
                "common":{"bdSnsKey":{},"bdText":"Java之集合框架　| FreeShow　","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"24"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
        </script>
    

    
</div>







    
      <div class="duoshuo" id="comments">
    <div id="comment-box" ></div>
    <div class="ds-thread" id="ds-thread" data-thread-key="Programming/Java/Java之集合框架/" data-title="Java之集合框架" data-url="https://freeshow.github.io/Programming/Java/Java之集合框架/"></div>
    <script>
        var duoshuoQuery = {short_name:"freeshowgithub"};
        var loadComment = function(){
            var d = document, s = d.createElement('script');
            s.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
            s.async = true; s.charset = 'UTF-8';
            (d.head || d.body).appendChild(s);
        }

        
    </script>
    
    <script> loadComment(); </script>

</div>
    




    <div class="scroll" id="post-nav-button">
        
            <a href="/Programming/Java/Java之字符串处理/" title="上一篇: Java之字符串处理">
                <i class="fa fa-angle-left"></i>
            </a>
        

        <a title="文章列表"><i class="fa fa-bars"></i><i class="fa fa-times"></i></a>

        
            <a href="/Programming/Scala/Scala访问控制修饰符/" title="下一篇: Scala访问控制修饰符">
                <i class="fa fa-angle-right"></i>
            </a>
        
    </div>

    <ul class="post-list"><li class="post-list-item"><a class="post-list-link" href="/BigData/Hadoop/Hadoop分布式集群安装/">Hadoop分布式集群安装</a></li><li class="post-list-item"><a class="post-list-link" href="/BigData/Hive/Hive应用实例：WordCount/">Hive应用实例：WordCount</a></li><li class="post-list-item"><a class="post-list-link" href="/BigData/Hive/Hive安装/">Hive安装</a></li><li class="post-list-item"><a class="post-list-link" href="/BigData/Hadoop/Windows下使用eclipse插件运行自己的MapReduce程序/">Windows下使用Eclipse插件运行自己的MapReduce程序</a></li><li class="post-list-item"><a class="post-list-link" href="/BigData/Hadoop/MapReduce之去重计数类应用/">MapReduce之去重计数类应用</a></li><li class="post-list-item"><a class="post-list-link" href="/BigData/Hadoop/MapReduce之简单排序类应用/">MapReduce之简单排序类应用</a></li><li class="post-list-item"><a class="post-list-link" href="/BigData/Hadoop/MapReduce之连接操作类应用/">MapReduce之连接操作类应用</a></li><li class="post-list-item"><a class="post-list-link" href="/BigData/Hadoop/MapReduce之计数类应用/">MapReduce之计数类应用</a></li><li class="post-list-item"><a class="post-list-link" href="/BigData/Hadoop/MapReduce之二次排序类应用/">MapReduce之二次排序类应用</a></li><li class="post-list-item"><a class="post-list-link" href="/BigData/Hadoop/MapReduce之倒排索引类应用/">MapReduce之倒排索引类应用</a></li><li class="post-list-item"><a class="post-list-link" href="/BigData/Hadoop/HDFS Java API/">HDFS Java API</a></li><li class="post-list-item"><a class="post-list-link" href="/BigData/Kafka/Kafka集群安装/">Kafka集群安装</a></li><li class="post-list-item"><a class="post-list-link" href="/BigData/Hadoop/Windows下使用eclipse编译打包运行自己的MapReduce程序 Hadoop2.6.0/">Windows下使用eclipse编译打包运行自己的MapReduce程序 Hadoop2.6.0</a></li><li class="post-list-item"><a class="post-list-link" href="/BigData/ZooKeeper/ZooKeeper集群安装/">ZooKeeper集群安装</a></li><li class="post-list-item"><a class="post-list-link" href="/BigData/Spark/Spark安装和集群部署/">Spark安装和集群部署</a></li><li class="post-list-item"><a class="post-list-link" href="/Comprehensive/BuildBlog/GitHub Pages + Hexo搭建个人博客/">GitHub Pages + Hexo搭建个人博客</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Python/Python爬虫实例：登录豆瓣并修改签名/">Python爬虫实例：登录豆瓣并修改签名</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Python/Python爬虫实例：用requests重构豆瓣热播电影爬虫/">Python爬虫实例：用requests重构豆瓣热播电影爬虫</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Python/Python爬虫实例：豆瓣热播电影/">Python爬虫实例：豆瓣热播电影（urllib+urllib2）</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Python/Python爬虫之requests介绍/">Python爬虫之requests介绍</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Python/Python爬虫之urllib2介绍/">Python爬虫之urllib2介绍</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Python/Python爬虫之urllib介绍/">Python爬虫之urllib介绍</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Python/Cookie介绍/">Cookie介绍</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Python/Python爬虫实例：从百度图片下载壁纸/">Python爬虫实例：从百度图片下载壁纸</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Python/Python线程/">Python线程</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Python/XPath与多线程爬虫/">XPath与多线程爬虫</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Python/Python之正则表达式/">Python之正则表达式</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Python/Python爬虫实例：唐诗三百首/">Python爬虫实例：唐诗三百首</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Python/Python爬虫进阶/">Python爬虫进阶</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Python/Python初步使用scrapy/">Python初步使用Scrapy</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Python/Python开发简单爬虫之实战演练/">Python开发简单爬虫之实战演练</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Python/Python开发简单爬虫之爬虫介绍（一）/">Python开发简单爬虫之爬虫介绍</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/FreeSwitch/FreeSwitch压力测试/">FreeSwitch压力测试</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/FreeSwitch/FreeSwitch使用mod-xml-curl提供动态用户管理/">FreeSwitch使用mod_xml_curl提供动态用户管理</a></li><li class="post-list-item"><a class="post-list-link" href="/Comprehensive/Tools/Win10下MarkdownPad安装及问题/">Win10下MarkdownPad安装及问题</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Linux/Ubuntu14-04安装Apache-php5-mysql-phpmyadmin/">Ubuntu14.04安装Apache+php5+mysql+phpmyadmin</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/C/Linux下C语言入门准备/">Linux下C语言入门准备</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Linux/vi编辑器/">vi编辑器</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Shell/Shell简单介绍/">Shell简单介绍</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Linux/linux基础（四）/">linux基础（四）</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Linux/Linux基础（三）/">Linux基础（三）</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Linux/Linux基础（二）/">Linux基础（二）</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Linux/Ubuntu Server 14.04 静态IP简单配置/">Ubuntu Server 14.04 静态IP简单配置</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Linux/Linux基础（一）/">Linux基础（一）</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之Handler详解（一）-关联到UI线程/">Android之Handler详解（一）---关联到UI线程</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之Handler详解（二）-关联到非UI线程/">Android之Handler详解（二）---关联到非UI线程</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之更新UI的方法/">Android之更新UI的方法</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之延迟执行某个任务/">Android之延迟执行某个任务</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/AndroidStudio之环境设置 /">初次安装AndroidStudio之环境设置</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Java/java里如何正确计算检验和/">java里如何正确计算检验和</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之AsyncTask介绍/">Android之AsyncTask介绍</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之Fragment（一）-简介/">Android之Fragment（一）--简介</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之Fragment（二）-使用/">Android之Fragment（二）--使用</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之Fragment（三）-生命周期与回退栈/">Android之Fragment（三）--生命周期与回退栈</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Java/Java运行时多态性：继承和接口的实现/">Java运行时多态性：继承和接口的实现</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之Fragment（四）-Fragment与Activity通讯/">Android之Fragment（四）--Fragment与Activity通讯</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之RAM、ROM和SD卡/">Android之RAM、ROM和SD卡</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之使用全局变量的两种方法/">Android之使用全局变量的两种方法</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之数据存储-SharedPreference/">Android之数据存储--SharedPreference</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之数据存储-File内部存储/">Android之数据存储--File内部存储</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之数据存储-外部存储（SD卡）/">Android之数据存储--外部存储（SD卡）</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之音频播放（MediaPlayer和SoundPool）/">Android之音频播放（MediaPlayer和SoundPool）</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之话筒、听筒、扬声器/">Android之话筒、听筒、扬声器</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之数据存数-SQLite数据库/">Android之数据存数--SQLite数据库</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之AdapterView及子类/">Android之AdapterView及子类</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之ListView和ListActivity-ArrayAdapter/">Android之ListView和ListActivity--ArrayAdapter</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之列表视图（LitView）-SimpleAdapter/">Android之列表视图（LitView）--SimpleAdapter</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之列表视图（LstView）-BaseAdapter/">Android之列表视图（LstView）--BaseAdapter</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之自动完成文本框（AutoCompleteTextView）/">Android之自动完成文本框（AutoCompleteTextView）</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之网格视图（GridView）/">Android之网格视图（GridView）</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之可扩展的列表组件（ExpandableListView）/">Android之可扩展的列表组件（ExpandableListView）</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/ListView的性能优化之convertView和viewHolder/">ListView的性能优化之convertView和viewHolder</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/android-layout-weight的真实含义/">android:layout_weight的真实含义</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Android/Android之使用9Patch图片作为背景/">Android之使用9Patch图片作为背景</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Java/Java综述/">Java综述</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Java/Java之数据类型、变量和数组/">Java之数据类型、变量和数组</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Java/Java之运算符/">Java之运算符</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Java/Java之控制语句/">Java之控制语句</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Java/Java之类/">Java之类</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Java/Java之方法和类的深入分析/">Java之方法和类的深入分析</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Java/Java之继承/">Java之继承</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Java/Java之包和接口/">Java之包和接口</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Java/Java之异常处理/">Java之异常处理</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Java/Java之多线程编程/">Java之多线程编程</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Java/Java之枚举、自动装箱与注解（元数据）/">Java之枚举、自动装箱与注解（元数据）</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Java/Java之I-O以及其它主题/">Java之I/O以及其它主题</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Java/Java之lambda表达式/">Java之lambda表达式</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Java/Java之字符串处理/">Java之字符串处理</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Java/Java之集合框架/">Java之集合框架</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Scala/Scala访问控制修饰符/">Scala访问控制修饰符</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Scala/Scala类/">Scala类</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Scala/Scala函数（一）/">Scala函数（一）</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Scala/Scala函数（二）/">Scala函数（二）</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Scala/Scala单例对象/">Scala单例对象</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/WebRTC/使用WebRTC搭建前端视频聊天室——信令篇/">使用WebRTC搭建前端视频聊天室——信令篇</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/WebRTC/使用WebRTC搭建前端视频聊天室——数据通道篇/">使用WebRTC搭建前端视频聊天室——数据通道篇</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/WebRTC/使用WebRTC搭建前端视频聊天室——点对点通信篇/">使用WebRTC搭建前端视频聊天室——点对点通信篇</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/WebRTC/WebRTC工作流程/">WebRTC工作流程</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/WebRTC/Android之WebRTC实现/">Android之WebRTC实现</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/WebRTC/Android之WebRTC介绍（二）/">Android之WebRTC介绍（二）</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/WebRTC/Android之WebRTC介绍（一）/">Android之WebRTC介绍（一）</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/WebRTC/WebRTC之turn服务器搭建/">WebRTC之turn服务器搭建</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/XMPP/openfire之SSL认证/">openfire之SSL认证</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/XMPP/基于openfire-smack开发Android即时聊天应用-一-用户注册、登陆、修改密码、注销等/">基于openfire+smack开发Android即时聊天应用[一]-用户注册、登陆、修改密码、注销等</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/OpenSIPs/ubuntu下opensips安装配置/">ubuntu下opensips安装配置</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Linux/计算机是如何启动的？/">计算机是如何启动的？</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Linux/Linux的启动流程/">Linux的启动流程</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/XMPP/Smack Message属性扩展---添加自定义元素(标签)/">Smack Message属性扩展--添加自定义元素（标签）</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/DataStructure/线性表-顺序表/">线性表---顺序表</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/SIP/SIP对话流程/">SIP对话流程</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/SIP/SIP服务器类型/">SIP服务器类型</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/SIP/SIP注册过程/">SIP注册过程</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/OpenSIPs/openSIPS路由类型/">openSIPS路由类型</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/OpenSIPs/opensips函数/">opensips函数</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/SIP/SIP路由字段和机理/">SIP路由字段和机理</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/OpenSIPs/opensips-csipsimple出现的各种问题/">opensips+csipsimple出现的各种问题</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/OpenSIPs/opensips介绍/">opensips介绍</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Shell/Shell编程（八）-输入输出重定向、文件包含/">Shell编程（八）---输入输出重定向、文件包含</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Shell/Shell编程（七）-函数/">Shell编程（七）---函数</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Shell/Shell编程（六）-循环/">Shell编程（六）---循环</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Shell/Shell编程（五）-if、case/">Shell编程（五）---if、case</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Shell/Shell编程（四）-echo、printf/">Shell编程（四）---echo、printf</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Shell/Shell编程（三）-字符串、数组/">Shell编程（三）---字符串、数组</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Shell/Shell编程（二）-替换、运算符、注释/">Shell编程（二）---替换、运算符、注释</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Shell/Shell编程（一）/">Shell编程（一）</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/WebRTC/使用WebRTC搭建前端视频聊天室——入门篇/">使用WebRTC搭建前端视频聊天室——入门篇</a></li><li class="post-list-item"><a class="post-list-link" href="/Comprehensive/BuildBlog/更改Yelee主题标签云为球形标签云/">更改Yelee主题标签云为球形标签云</a></li><li class="post-list-item"><a class="post-list-link" href="/Communication/FreeSwitch/FreeSwitch安装文档/">FreeSwitch安装文档</a></li><li class="post-list-item"><a class="post-list-link" href="/Comprehensive/BuildBlog/Hexo主题Yelee介绍/">Hexo主题Yelee介绍</a></li><li class="post-list-item"><a class="post-list-link" href="/Programming/Linux/Ubuntu14-04安装JDK与配置环境变量/">Ubuntu14.04安装JDK与配置环境变量</a></li></ul>




    <script>
        
    </script>
</div>
      <footer id="footer">
    <div class="outer">
        <div id="footer-info">
            <div class="footer-left">
                <i class="fa fa-copyright"></i> 
                2016-2017 FreeShow
            </div>
            <div class="footer-right">
                <a href="http://hexo.io/" target="_blank" title="快速、简洁且高效的博客框架">Hexo</a>  Theme <a href="https://github.com/MOxFIVE/hexo-theme-yelee" target="_blank" title="简而不减 Hexo 双栏博客主题  v3.5">Yelee</a> by MOxFIVE <i class="fa fa-heart animated infinite pulse"></i>
            </div>
        </div>
        
            <div class="visit">
                
                    <span id="busuanzi_container_site_pv" style='display:none'>
                        <span id="site-visit" title="本站到访数"><i class="fa fa-user" aria-hidden="true"></i><span id="busuanzi_value_site_uv"></span>
                        </span>
                    </span>
                
                
                    <span>| </span>
                
                
                    <span id="busuanzi_container_page_pv" style='display:none'>
                        <span id="page-visit"  title="本页阅读量"><i class="fa fa-eye animated infinite pulse" aria-hidden="true"></i><span id="busuanzi_value_page_pv"></span>
                        </span>
                    </span>
                
            </div>
        
    </div>
</footer>
    </div>
    
    <script src="/js/GithubRepoWidget.js"></script>

<script data-main="/js/main.js" src="//cdn.bootcss.com/require.js/2.2.0/require.min.js"></script>

    <script>
        $(document).ready(function() {
            var iPad = window.navigator.userAgent.indexOf('iPad');
            if (iPad > -1 || $(".left-col").css("display") === "none") {
                var bgColorList = ["#9db3f4", "#414141", "#e5a859", "#f5dfc6", "#c084a0", "#847e72", "#cd8390", "#996731"];
                var bgColor = Math.ceil(Math.random() * (bgColorList.length - 1));
                $("body").css({"background-color": bgColorList[bgColor], "background-size": "cover"});
            }
            else {
                var backgroundnum = 5;
                var backgroundimg = "url(/background/bg-x.jpg)".replace(/x/gi, Math.ceil(Math.random() * backgroundnum));
                $("body").css({"background": backgroundimg, "background-attachment": "fixed", "background-size": "cover"});
            }
        })
    </script>





    <script type="text/x-mathjax-config">
MathJax.Hub.Config({
    tex2jax: {
        inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
        processEscapes: true,
        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
    }
});

MathJax.Hub.Queue(function() {
    var all = MathJax.Hub.getAllJax(), i;
    for(i=0; i < all.length; i += 1) {
        all[i].SourceElement().parentNode.className += ' has-jax';                 
    }       
});
</script>

<script src="//cdn.bootcss.com/mathjax/2.6.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>


<div class="scroll" id="scroll">
    <a href="#" title="返回顶部"><i class="fa fa-arrow-up"></i></a>
    <a href="#comments" onclick="load$hide();" title="查看评论"><i class="fa fa-comments-o"></i></a>
    <a href="#footer" title="转到底部"><i class="fa fa-arrow-down"></i></a>
</div>
<script>
    // Open in New Window
    
        var oOpenInNew = {
             github: ".github-widget a", 
            
            
            
            
            
             archives: ".archive-article-title", 
             miniArchives: "a.post-list-link", 
            
             friends: "#js-friends a", 
             socail: ".social a" 
        }
        for (var x in oOpenInNew) {
            $(oOpenInNew[x]).attr("target", "_blank");
        }
    
</script>

<script async src="https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js">
</script>
  </div>
</body>
</html>